# -*- coding: utf-8 -*-
import os
import time
import socket
from PodcastTaggerLogging import *
import lxml.etree as etree
import urllib
from urlparse import urlparse

class PodcastFeed:
    def __init__(self,p,u):
        self.clear()
        self.path = p
        self.url = u

    def clear(self):
        self.url = ''
        self.title = ''
        self.author = ''
        self.path = ''
        self.date_formats_in = ['%a,%d %b %Y %H:%M:%S',
                                '%a, %d %b %Y %H:%M:%S',
                                '%a, %d %b %Y %H:%M',
                                '%d %b %Y %H:%M:%S',
				'%d %b %Y %H:%M:%S %Z']
        self.df_conversions = {"Tues":"Tue","Thurs":"Thu","Sept":"Sep","June":"Jun","July":"Jul"}
        self.date_format_out = '%Y-%m-%d'
        self.items = []
        self.rootNode = None

    def read(self):
        ptlogger.debug('Reading Podcast (\"%s\",\"%s\")',self.path,self.url)
        ptlogger.debug('Pinging Host %s',urlparse(self.url)[1])
        nPings = 1
        os.system('ping -c ' + str(nPings) + ' ' + urlparse(self.url)[1] + ' > /dev/null 2>&1')
        ptlogger.debug('Opening Feed')
        #reader = Sax2.Reader()
        if self.url != '' and self.path != '':
            try:
                #self.rootNode = reader.fromStream(self.url)
		#u = urllib.urlopen(self.url)
                self.rootNode = etree.parse(self.url).getroot()
                self.nsmap = self.rootNode.nsmap
                self.channelNode = self.rootNode.find('channel')
                #u.close()
                self.getPodcastTitle()
                self.getPodcastAuthor()
                self.matchToFiles()
            except socket.error:
                ptlogger.error('Socket Error')
        ptlogger.debug('Fininshed Reading Podcast(\"%s\",\"%s\")',self.path,self.url)

    # Get the 'title' node of the feed
    def getPodcastTitle(self):
        self.title = self.channelNode.find('title').text.encode('ascii','ignore')

    def getPodcastAuthor(self):
        self.author = self.channelNode.find('{' + self.nsmap['itunes'] + '}author').text.encode('ascii','ignore')

    # Get a list of all 'item' nodes in the feed
    def getPodcastItems(self):
        return self.channelNode.findall('item')

    # Get the 'title' node of a podcast item
    def getItemTitle(self,item):
        titleNode = item.find('title')
        if titleNode != None and len(titleNode.text) > 0:
            return titleNode.text
        else:
            return ''

    # Get the 'description' node of a podcast item
    def getItemDescription(self,item):
        descNode = item.find('description')
        if descNode != None and len(descNode.text) > 0:
            return descNode.text
        else:
            return ''

    def getItemDate(self,item):
        ptlogger.debug('getItemDate(), podcast %s',self.path.split('/')[-1])
        dn = item.find('pubDate')
        if dn != None:
            try:
                date_str = ' '.join(dn.text.split(' ')[:-1])
                #Go through the date string to replace any non-conforming abbreviations
                #(i.e., "Sept" instead of "Sep").
                for bad,good in self.df_conversions.iteritems():
                    date_str = date_str.replace(bad,good)

                ptlogger.debug('date_str = \"%s\"',date_str)
                t = None
                for df in self.date_formats_in:
                    ptlogger.debug('Trying date format \"%s\"',df)
                    try:
                        t = time.strptime(date_str,df)
                        ptlogger.debug('Succeeded')
                        break
                    except ValueError:
                        ptlogger.debug('Failed')
                if t == None:
                    ptlogger.error('All date formats failed')
                else:
                    ptlogger.debug('%s',time.strftime(self.date_format_out,t))
                    return time.strftime(self.date_format_out,t)
            except ValueError:
                ptlogger.error('ValueError while parsing pubDate')
        return None

    # Get the URL of a podcast item
    def getItemURL(self,item):
        enclosure = item.find('enclosure')
        if enclosure != None:
	    return enclosure.attrib['url']
        return None

    # Get the filename of a podcast item
    def getItemFilename(self,item):
        url = self.getItemURL(item)
        if url != None:
            return urlparse(url)[2].split('/')[-1]
        return ''

    # Analyzes the podcast items found in XML Feed, and compares them to the files
    # located in directory "path". Returns a list of lists. Each entry is a list of length
    # three, with the following values:
    # 	1) Podcast File Path
    # 	2) Podcast Title
    #	3) Publication Date
    def matchToFiles(self):
        self.items = []
        raw_items = self.getPodcastItems()
        for i in raw_items:
            filename = self.getItemFilename(i)
            if filename in os.listdir(self.path):
                self.items.append([self.path + "/" + filename,
                                    self.getItemTitle(i).encode('ascii','ignore'),
                                    self.getItemDate(i)])
